/** 数据库缓存，缓存最近打开的数据库（针对登录用户）
 * @file dbcache.cpp
 * @author Kiven Lee
 * @version 1.0
 * @date 2022-03-29
 *
 * @copyright Kivensoft (c) 2018 - 2022
 *
 */

#include "dbcache.hpp"
#include "klib/log.hpp"

using namespace ai;

cache_item_t* db_cache_t::get(const std::string_view& user) {
    auto iter = std::find_if(_items.begin(), _items.end(),
            [&user] (auto v) { return v->user == user; });
    return iter != _items.end() ? *iter : nullptr;
}

cache_item_t* db_cache_t::get_by_token(const std::string_view& token) {
    auto iter = std::find_if(_items.begin(), _items.end(),
            [&token] (auto v) { return v->token == token; });
    return iter != _items.end() ? *iter : nullptr;
}

void db_cache_t::_put(cache_item_t* item) {
    for (auto iter = _items.begin(), iend = _items.end(); iter != iend; ++iter) {
        if ((*iter)->user == item->user) {
            delete *iter;
            *iter = item;
            return;
        }
    }
    _items.emplace_back(item);
}

void db_cache_t::gc() {
    time_t now = std::time(nullptr);

    for (auto iter = _items.begin(), e = _items.end(); iter != e; ) {
        // 到期session的删除
        time_t exp = (*iter)->expire;
        if (exp != 0 && exp < now) {
            LOG_TRACE("session到期，删除session：user = {}", (*iter)->user);
            delete *iter;
            _items.erase(iter++);
            break;
        }

        // 到期数据库缓存删除
        exp = (*iter)->db_expire;
        if ((*iter)->db_expire != 0 && (*iter)->db_expire < now) {
            LOG_TRACE("数据库缓存到期，关闭该数据库: {}", (*iter)->db->dbname());
            (*iter)->db.reset();
            (*iter)->db_expire = 0;
        }
    }
}
